<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Administrator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class ManagerController extends Controller
{
    public function store(Request $request)
    {
        $validator = validator(
            $request->only(['real_name', 'account', 'phone', 'password', 'roles', 'status']),
            [
                'real_name' => 'required',
                'account' => 'required',
                'phone' => ['required', 'regex:/^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[235-8]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|66\d{2})\d{6}$/'],
                'password' => 'required',
                'roles' => 'required',
                'status' => 'in:' . implode(',', [Administrator::STATUS_NORMAL, Administrator::STATUS_DISABLE])
            ],
            [
                'real_name.required' => trans('conventional.validator_required', ['field' => trans('noun.real_name')]),
                'account.required' => trans('conventional.validator_required', ['field' => trans('noun.account')]),
                'phone.required' => trans('conventional.validator_required', ['field' => trans('noun.phone_number')]),
                'phone.regex' => trans('conventional.validator_regex', ['field' => trans('noun.phone_number')]),
                'password.required' => trans('conventional.validator_required', ['field' => trans('noun.password')]),
                'roles.required' => trans('conventional.validator_required', ['field' => trans('noun.role')]),
                'status.in' => trans('conventional.validator_in', ['field' => trans('noun.status'), 'range' => '']),
            ]);
        if (($errors = $validator->errors())->isNotEmpty()) {
            $this->response->errorBadRequest(
                implode(',',
                    array_values(
                        array_map(
                            function ($error) {
                                return $error[0];
                            },
                            $errors->toArray()))));
        }

        DB::beginTransaction();
        try {
            /** @var Administrator $admin */
            $admin = Administrator::create([
                'real_name' => $request->get('real_name'),
                'account' => $request->get('account'),
                'phone' => $request->get('phone'),
                'password' => Hash::make($request->get('password'))
            ]);

            $admin->assignRole($request->get('roles'));

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();

            if (
                $e instanceof \PDOException
                && (int) ($e->errorInfo[1] ?? 0) === 1062
                && (int) $e->getCode() === 23000) {

                $this->response->errorBadRequest(
                    trans(
                        'auth.has_registed',
                        [
                            'field' => [
                                'phone' => trans('noun.phone_number'),
                                'account' => trans('noun.account')
                            ][explode('_', Str::afterLast($e->errorInfo[2], 'key'))[1]] // 已存在的字段
                        ])
                );
            }

            $this->response->errorBadRequest($e->getMessage());
        }

        return $this->response->created(null, $admin);
    }

    public function update(Request $request)
    {
        $manager = null;
        try {
            $manager = Administrator::query()
                ->withoutGlobalScope('status')
                ->findOrFail($request->get('id'));

            if (($status = (int) $request->get('status')) &&
                in_array($status, [Administrator::STATUS_NORMAL, Administrator::STATUS_DISABLE], true)) {

                $manager->status = $status;
            }

            $manager->save();
        } catch (\Exception $e) {
            $this->response->errorBadRequest($e->getMessage());
        }

        return $this->response->created(null, $manager);
    }

    public function list(Request $request)
    {
        return $this->response->array(
            Administrator::query()
                ->withoutGlobalScope('status')
                ->with('roles:name')
                ->when($request->get('account'), function (Builder $query, $account) {
                    $query->where('account', 'like', '%' . $account . '%');
                })
                ->when($request->get('real_name'), function (Builder $query, $realName) {
                    $query->where('real_name', 'like', '%' . $realName . '%');
                })
                ->when($request->get('phone'), function (Builder $query, $phone) {
                    $query->where('phone', 'like', '%' . $phone . '%');
                })
                ->when($request->get('status'), function (Builder $query, $status) {
                    $query->where('status', $status);
                })
                ->when($request->get('created_at_begin'), function (Builder $query, $createdAtBegin) {
                    $query->where('created_at', '>=', $createdAtBegin);
                })
                ->when($request->get('created_at_end'), function (Builder $query, $createdAtEnd) {
                    $query->where('created_at', '<=', Carbon::parse($createdAtEnd)->endOfDay());
                })
                ->when($request->get('role'), function (Builder $query, $role) {
                    $query->role($role);
                })
                ->paginate());
    }
}
